package com.itheima.reggie.filter;

import com.alibaba.fastjson.JSON;
import com.itheima.reggie.common.BaseContext;
import com.itheima.reggie.common.R;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.AntPathMatcher;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * @author ：sean
 * @date ：Created in 2022/5/18
 * @description ：这个过滤器，做登录检查
 * 判断当前是否登录过，相当于安全检查
 * @version: 1.0
 */
@WebFilter(filterName = "loginCheckFilter",urlPatterns = "/*")
@Slf4j
public class LoginCheckFilter implements Filter {

	// 定义一个数组，把不需要处理的URI存起来
	private String[] authUrl = new String[]{
		"/backend/**",
		"/front/**",
		"/employee/login",
		"/employee/logout",
		"/common/**",
		"/user/sendMsg", // 移动端的发送短信
		"/user/login"    // 移动端登录
	};
	@Override
	public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse,
						 FilterChain filterChain) throws IOException, ServletException {
		//拦截所有请求 包括了静态和动态的资源
		HttpServletRequest request = (HttpServletRequest)servletRequest;
		HttpServletResponse response = (HttpServletResponse)servletResponse;
		// 结论：静态资源全部放行
		// 动态资源：/employee/login /employee/logout 这2个放行，
		// 其他动态资源，必须登录才可以访问，否则调回到登录页
		// 1.获取URI
		// /employee/page
		String uri = request.getRequestURI();
		log.info("[登录检查过滤器...],当前uri:{}",uri);
		// 确定哪些URI是放行 登录页面放行，静态资源
		//  /backend/*,front/*
		//  /employee/login /employee/logout
		// 2.判断URI是否需要处理（是否拦截）
		boolean isAuth = checkURI(uri);
		// 3.如果不需要拦截，就放行
		if(isAuth){
			// 所有静态资源都放行
			log.info("[登录检查过滤器],允许放行");
			filterChain.doFilter(request,response);
			return;
		}
		///employee/page，这个资源需要验证是否登录过
		// 4.如果需要，判断是否登录过（后台登录）
		if(request.getSession().getAttribute("employee")!=null){
			log.info("[登录检查过滤器],已登录，允许通过");
			Thread thread = Thread.currentThread();
			log.info("[登录检查过滤器],已登录，允许通过: 当前线程ID:{}",thread.getId());
			Long empId = (Long)request.getSession().getAttribute("employee");
			BaseContext.setCurrentId(empId);
			filterChain.doFilter(request,response);
			return;
		}
		// 判断移动端是否登录过（后台登录）
		if(request.getSession().getAttribute("user")!=null){
			log.info("[登录检查过滤器],移动端已登录，允许通过");
			Thread thread = Thread.currentThread();
			log.info("[登录检查过滤器],移动端已登录，允许通过: 当前线程ID:{}",thread.getId());
			Long userId = (Long)request.getSession().getAttribute("user");
			BaseContext.setCurrentId(userId);
			filterChain.doFilter(request,response);
			return;
		}
		// 5.如果未登录，返回未登录的错误信息,前端工程师根据字符串做跳转
		response.getWriter().write(JSON.toJSONString(R.error("NOTLOGIN")));
	}

	private boolean checkURI(String reqUri) {
		// 这个类，可以匹配通配符
		AntPathMatcher pathMatcher = new AntPathMatcher();
		// 这里面处理逻辑
		// 遍历数组，让数组的每个元素与当前的uri比对
		// /backend/index.html
		for (String url:authUrl){
			// /backend/*
			// /backend/page/login/login.html
			// /backend/plugins/axios/axios
			if(pathMatcher.match(url,reqUri)){
				log.info("[登录检查过滤器],匹配放行的url:{}",url);
				return true;
			}
		}
		return false;
	}

	@Override
	public void init(FilterConfig filterConfig) throws ServletException {

	}

	@Override
	public void destroy() {

	}


}
